﻿using System.Diagnostics;

namespace Micro.Common.Helper
{
    public sealed partial class CommonHelper
    {
        private static readonly object fileLocker = new object();

        /// <summary>写入日志信息,写入控制台，自动删除上月日志
        /// 写入日志信息,写入控制台，自动删除上月日志
        /// </summary>
        /// <param name="strLog"></param>
        public static void WriteLog(string strLog, bool consoleStr = false)
        {
            try
            {
                var dt = DateTime.Now;
                string sFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "Logs\\" + dt.ToString("yyyyMM");
                string sFilePathOld = System.AppDomain.CurrentDomain.BaseDirectory + "Logs\\" + dt.AddMonths(-1).ToString("yyyyMM");
                string sFileName = "日志" + dt.ToString("dd") + ".log";
                sFileName = sFilePath + "\\" + sFileName; //文件的绝对路径
                Monitor.Enter(fileLocker);
                if (!Directory.Exists(sFilePath))//验证路径是否存在
                {
                    Directory.CreateDirectory(sFilePath);
                    //不存在则创建
                }
                try
                {
                    if (Directory.Exists(sFilePathOld))
                        Directory.Delete(sFilePathOld, true);
                }
                catch (Exception ex) { strLog += "；" + ex.Message; }

                FileStream fs;
                StreamWriter sw;
                if (File.Exists(sFileName))
                //验证文件是否存在，有则追加，无则创建
                {
                    fs = new FileStream(sFileName, FileMode.Append, FileAccess.Write);
                }
                else
                {
                    fs = new FileStream(sFileName, FileMode.Create, FileAccess.Write);
                }
                sw = new StreamWriter(fs);
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "---" + strLog);
                if (consoleStr)
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "---" + strLog);
                sw.Close();
                fs.Close();
            }
            catch (Exception) { }
            finally
            {
                Monitor.Exit(fileLocker);
            }
        }

        /// <summary>
        /// 获取上两级方法名称（不包含当前方法）
        /// </summary>
        /// <param name="top">0.本級目錄：GetMethodName，1.包含GetMethodName的上級 2.包含第一點的上級</param>
        /// <param name="isIntercept">截取字符串</param>
        /// <param name="isTwoLevel"></param>
        /// <returns></returns>
        public static string GetMethodName(int top = 1, bool isIntercept = true, bool isTwoLevel = true)
        {
            var methodName = $"{(isTwoLevel ? $"C:{new StackTrace(true).GetFrame(top + 1).GetMethod().Name}:" : default)}{new StackTrace(true).GetFrame(top).GetMethod().Name}";
            if (isIntercept && methodName.Length > 50) methodName = methodName.Substring(methodName.Length - 50);
            return methodName;
        }

        /// <summary>
        /// 将 Stream 转成 byte[]：可防卡死
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static byte[] StreamToBytesAsync(Stream stream)
        {
            var bytes = new byte[0];
            if (stream is null) return bytes;
            try
            {
                using (var ms = new MemoryStream())
                {
                    stream.CopyToAsync(ms).Wait(1000 * 30);
                    bytes = ms.ToArray();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"异常信息:{ex.Message}");
            }
            return bytes;
        }

        /// <summary>
        /// 将 Stream 转成 byte[]
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        /// <summary>
        /// 将 byte[] 转成 Stream
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }

        /// <summary>
        /// Stream转换MemoryStream
        /// </summary>
        /// <param name="instream"></param>
        /// <returns></returns>
        public static MemoryStream StreamToMemoryStream(Stream instream)
        {
            MemoryStream outstream = new MemoryStream();
            instream.CopyTo(outstream);
            return outstream;
        }
    }
}